This repository was archived by the owner on Sep 8, 2025. It is now read-only.
Merged
Conversation
* Simplify WASI internal implementations This commit migrates the WASIp2 implementation to be closer to the upcoming WASIp3 implementation in terms of how things are implemented internally. Previously the way things worked with WASIp2 is: * Embedders call `add_to_linker` with `T: WasiView` * Internally `add_to_linker` is called which creates `WasiImpl<&mut T>` * All internal implementations were `impl<T> Host for WasiImpl<T> where T: WasiView` * A forwarding impl of `impl<T: WasiView> WasiView for &mut T` was required While this all worked it's a bit complicated for a few reasons: 1. Dealing with generically named structures like `WasiImpl` (or `IoImpl` or `WasiHttpImpl`) is a bit baroque and not always obvious as to what's going on. 2. The extra layer of generics in `impl<T> Host for WasiImpl<T>` adds a layer of conceptual indirection which is non-obvious. 3. Other WASI proposal implementations do not use this strategy and instead use "view" types or `impl Host for TheType` for example. 4. Internal incantations of `add_to_linker` had to deal with mixtures of `IoImpl` and `WasiImpl` and aligning everything just right. 5. An extra layer of generics on all impls meant that everything was generic meaning that `wasmtime-wasi`-the-crate didn't generate much code, causing longer codegen times for consumers. The goal of this commit is to migrate towards the style of what WASIp3 is prototyping for how impls are modeled. This is done to increase the amount of code that can be shared between WASIp2 and WASIp3. This has a number of benefits such as being easier to understand and also being more modular where `wasi:clocks` implementations of traits don't require filesystem context to be present (as is the case today). This in theory helps a more mix-and-match paradigm of blending together various bits and pieces of `wasmtime-wasi` implementations. Concretely the changes made here are: * `WasiView` no longer inherits from `IoView`, they're unrelated traits now. * `WasiView` now returns `WasiViewCtx<'a>` which has `ctx: &'a mut WasiCtx` and `table: &'a mut ResourceTable`. That means it basically does the same thing before but in a slightly different fashion. * Implementations of `Host` traits are now directly for `WasiCtxView<'_>` and don't involve any generics at all. These are hopefully easier to understand and also better from a codegen/compile-time perspective. * Embedders no longer need to implement `IoView` directly and instead fold that functionality into `WasiView`. * `WasiHttpView` no longer inherits from `IoView` and instead has a direct `fn table` method. Additionally `WasiHttpImpl` no longer embeds `IoImpl` inside of it. * Host traits for `wasi:io` are now implemented directly for `ResourceTable` instead of `IoImpl<T>`. The immediate goal of this refactoring is to enable more sharing along the lines of #11362. This was not possible prior because WASIp3 requires a simultaneous borrow on the table/ctx while the trait hierarchy previously gave you one-or-the-other. With this new organization it will be possible to get both at the same time meaning more structure/contexts/etc can be shared between implementations. prtest:full * CI fixes * More CI fixes * More CI fixes
* Share stdio implementations in WASIp{2,3}
This commit is a refactoring of the
`wasmtime_wasi::{cli,p2::stdio,p3::cli}` modules to share more code. The
generic trait object that represents stdio now has the ability to
acquire either a p2 stream or an async-based stream. The acquisition of
p2 has a default implementation so in the future this can be primarily
`Async{Read,Write}`-based.
Many trait implementations and types and such were all consolidated
together into the `wasmtime_wasi::cli` module. One-off implementations
in p2/p3 are now shared in one location and `WasiCtxBuilder` no longer
needs any generics for different stdio streams.
Functionally this necessitated the addition of `Async{Read,Write}`
implementations for some "base" implementations of stdio primitives.
Implementations were mostly trivial except for a few adapters which were
significantly more complicated, namely the `Async{Read,Write}Stream`
adapter which converts a single `Async{Read,Write}` into the stdio of a
component.
Finally the stdin implementation for p3 was refactored to avoid use of
`tokio::io::stdin()` which generally isn't safe to use. It's replaced
with a custom `AsyncRead` using the worker thread implementation we have
in the crate already.
Eventually I hope to remove the distinction between `p{2,3}::WasiCtx`
and have these be the same type. This will make it nicer to only have a
single `WasiView` trait and additionally make it easier to
simultaneously implement all of WASIp{1,2,3}.
* Fix build of C API
* Fix build of `wasmtime serve`
This commit updates to using the `trappable_error_type` in bindings generated for WASIp3 to mirror what happens in WASIp2, removing an extra `Result<Result<..>>` layer to only have one layer of results.
This removes `wasmtime_wasi::p{2,3}::{WasiCtx, WasiCtxBuilder,
WasiView}` in favor of only having `wasmtime_wasi::{WasiCtx,
WasiCtxBuilder, WasiView}` instead. Conceptually these revisions of WASI
all provide the same functionality just with a different veneer that the
component model offers, so having only one way to configure host-side
behavior will make it easier to both organize implementations internally
(e.g. more sharing of code) as well as for embedders to configure (only
one context to create/manage).
Co-authored-by: Wasmtime Publish <wasmtime-publish@users.noreply.github.com>
* Mirror WASIp{2,3} cli implementations
This is an implementation of #11362 but for the `wasi:cli`
implementation of WASIp2.
* Fix unused field without p3
This is an implementation of #11362 but for the `wasi:clocks` implementation of WASIp2. The goal here is to have the impls be implemented and look roughly the same across WASIp2 and WASIp3, namely the target of the implementation of now `WasiClocksCtxView` instead of `WasiCtxView`. This makes the trait implementations a bit more flexible as it means embedders aren't required to, for example, provide a full WASI context for clocks but just clock-related context.
This is an implementation of #11362 but for the `wasi:sockets` implementation of WASIp2. This additionally internalizes much of the WASIp3 implementation with `pub(crate)` to avoid unnecessarily exposing implementation details of the crate.
* Rename "preview{0,1}" in `wasmtime-wasi` to "p{0,1}"
This commit renames the `preview1` module and features to `p1` and does
the same for `preview0`. This additionally cleans up the test suite a
bit to share more code amongst all the implementaitons and to also move
the p1 tests out of the p2 folder.
This additionally adds a `p2` feature to the `wasmtime-wasi` crate but
it does not currently gate the `p2` module because that'll require some
more refactoring an annotations to get that working.
* Fix build of the CLI
* Fix build of the C API
* Fix bench-api build
* Fix build of examples
* More renamings
* Use the same `UdpSocket` in WASIp{2,3}
This commit refactors the implementation of `wasi:sockets` for WASIp2
and WASIp3 to use the same underlying host data structure for the
`UdpSocket` resource in WIT. Previously each version of WASI had its own
socket which resulted in duplicated code. There's some minor differences
between WASIp2 and WASIp3 but it's easy enough to paper over with the
same socket type. This is intended to help with the maintainability of
this going forward to only have one type to operate on rather than two
(which also ensures that bugfixes for one should affect the other).
One other change made in this commit is that sprinkled checks for
whether or not UDP is allowed are all removed and canonicalized during
UDP socket creation. This means that UDP socket creation is the only
location that checks for whether UDP is allowed. Once a UDP socket is
created it can be used freely regardless of whether the UDP setting is
enabled or disabled. This is not intended to have a large practical
effect but it does mean the behavior of hosts that deny UDP but manually
give access to a UDP socket resource to a component may behave subtly
differently.
* Review comments
* Fix p3-less warnings
* Update UDP denial test
* Fix some clippy issues
* Fix no-udp test warnings
* asm: generate boolean terms of CPU features As discussed [here], we will soon need the ability to express more complex combinations of CPU features. These are best expressed as boolean terms: e.g., `(32-bit OR 64-bit) AND ...`, `(32-bit OR 64-bit) AND ((AVX512VL AND AVX512F) OR AVX10.1)`. This change modifies the generated code to have a `Inst::is_available` method which contains a Rust-ified version of the instruction's boolean term. To do this, we now pass in a `Features` trait, which the instruction can query to see if its desired feature set is available. [here]: https://bytecodealliance.zulipchat.com/#narrow/channel/217117-cranelift/topic/boolean.20terms.20for.20x64.20features * x64: wire up `Inst::is_available` in Cranelift This change makes us of the assembler's new generated `Inst::is_available` methods to check an instruction's feature set in a more succinct (and likely quicker) way. Unfortunately, this does not allow us to print the missing ISA requirements on failure--something to address later. * Rename `Features` to `AvailableFeatures` * Remove unused `InstructionSet` * asm: fix all feature definitions This is a mechanical transformation converting all instruction definitions. Now, instructions should have a correct boolean term describe the features required: e.g., `(_64b | compat) & avx`. * x64: replace `use_*` with `has_*` when checking ISA features In Cranelift, the `has_*` flags of `isa::x64::settings::Flags` indicate that the CPU _has_ some capability; the `use_*` flags indicate that Cranelift _should emit_ instructions using those capabilities. Further, the `use_*` flags may turned on by the presence of more than one `has_*` flags; e.g., when `has_avx` and `has_avx2` are available, `use_avx2` is enabled. Now that Cranelift's new x64 assembler understands boolean terms, we no longer need the `use_*` flags for checking if an instruction can be emitted: instead, we should use the `has_*` flags and rely on the logic encoded in `Inst::is_available`. * asm: materialize `Features` via `Inst::features` For better error messages (and just for general use of CPU features, see discussion [here]), this change adds `Inst::features`--a way to explicitly examine the boolean term for an instruction. This function returns a `&'static Features` that contains the `AND` and `OR` branches defining when an instruction is available. This is all generated into something that looks like: ```rust pub fn features(&self) -> &'static Features { const F1: &'static Features = &Features::Feature(Feature::_64b); const F2: &'static Features = &Features::Feature(Feature::compat); const F0: &'static Features = &Features::Or(F1, F2); F0 } ``` This change makes use of `for_each_feature` more: we build up the `AvailableFeatures` trait and the `Feature` enum from it. This should be a bit more direct than searching through the generated code (?). [here]: bytecodealliance/wasmtime#11272 (comment)
In #11344 it was found that if Wasmtime had a frame on the stack then an application's previous unwinding was broken. This was due to the fact that Wasmtime's C API artifacts do not have unwind information built-in due to being build with `-Cpanic=abort`. This change updates to building the C API artifacts with `-Cforce-unwind-tables` even though Rust itself won't use them to assist with embedders that want to unwind. These should in theory be easily strippable if desired and additionally embedders always have the option to build their own version of the C API too. Closes #11344
…llation (#11329) * Notify new terminal needs to be opened after wastime installation * Notify on-screen instructions need to be followed after wastime installation
In addition to keeping things up-to-date this enables testing the `tail_loop` interpreter mode of Pulley using the `become` keyword and native Rust syntax. This still isn't ready for prime-time so it's just as gated as before, but we can promote a `cargo check` to a `cargo test` in CI.
* Use the same `TcpSocket` in WASIp{2,3}
This is the same as #11384 except for `TcpSocket` to share the
implementation of TCP across WASIp{2,3} and avoid duplicating code
between the two.
* Fix CI issues
* Review comments
* Trim "TCP allowed?" checks
Like UDP only perform the check on socket creation, not after it's
created.
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
…ining (#11389) This was an entity that we forgot to translate from the callee into the caller. Note that we do not use the `EntityMap` offset approach for these entities because `ir::Function` hash-conses them.
* Bump MSRV to Rust 1.87.0 Coincides with today's release of Rust 1.89 * Fix some lint warnings * Fix tests with Pulley * Fix lldb tests * Fix a doc test on 32-bit
* Further expand differential fuzzing documentation Split out the list of non-deterministic behaviors to its own separate section to both make it more easy to scan over and additionally have more fuzzing-related discussion such as generating programs that bake-in NaN canonicalization. I've also updated this to include WASIp1 APIs to discourage differential fuzzing of WASIp1 as the proposal is effectively not suitable for this. I've noted, though, that WASIp2-and-beyond should be suitable for differential fuzzing. * Be bold.
ASAN is the longest builder right now and many of the slow tests aren't really buying much such as: * `disas` - no `unsafe` code * `wast` - no need to test all permutations of compilers/collectors and instead one should suffice * `all` - various tests taking 1m+ were flagged to ignore under ASAN as it's not necessarily important to run 100% of tests under ASAN.
Use `*::cast_{un,}signed` in the Rust standard library stabilized in
1.87.
This was no longer needed, and was adding build time to testing wasmtime (rebuilt every time wasmtime changes, because it depends on wasmtime) for no reason prtest:full
Checking for the tombstone address during the reachability calculation allows more DWARF entries to be marked as unreachable, and there was already code to handle this for addresses left as 0.
This opts-in to a new Clippy lint which is intended to help clean up historical refactorings to ensure that bounds on type parameters are either in the type parameter declaration or in a `where` clause, but not both.
* WIP: use the pagemap_scan ioctl to selectively reset an instance's dirty pages * Less hacky, and supporting tables, too * Bugfixes * WIP: memcpy instead of pread * Refactor support for pagemap * Don't hold a raw pointer to the original data, plumb through an `Arc` to have a safe reference instead. * Update pagemap bindings to latest version of abstraction written. * Include pagemap-specific tests. * Use a `PageMap` structure created once-per-pool instead of a static-with-a-file. * Refactor to use the "pagemap path" unconditionally which blends in the keep_resident bits. * Improve safety documentation prtest:full * Fix some lints * Skip ioctl tests when it's not supported * Fix a memory leak by moving impls around * Fix no vm build * Review comments * Add more pagemap-specific documentation * Add more docs, refactor implementation slightly * Improve `category_*` docs Basically forward to the Linux kernel source itself. * Fix compile * Make pagemap integration resilient across forks * Fix non-pooling-allocator-build * Fix portability issues of new test * Actually use config on macos --------- Co-authored-by: Till Schneidereit <till@tillschneidereit.net>
We would previously always create Cranelift `ir::FuncRef`s for the callee of a Wasm `call` instruction, even if that was a call to an imported function that actually gets translated to an indirect call in CLIF. This commit makes it so that we delay `ir::FuncRef` creation until we actually emit a direct call. Also I found that we were not looking for already-created `ir::SigRef`s when creating `ir::FuncRef`s, so I fixed that as well, which removes a couple duplicate signature definitions in our disas tests.
* Remove a dead trait method Made obsolete from previous refactorings, so no need to keep this any more. * Fix unused import * Fix missing import
This cannot be an `unsafe` method as it's not possible to provide the guarantee that the memory is placed back in the store (e.g. `forget`-ing futures). Instead make the method more strict and say that panics will happen if `replace_memory` isn't called. Existing implementations should already adhere to this.
Closes #11412
* Minimize lazy allocation of the GC store
This commit is an effort to minimize the number of entrypoints which
might lazily allocate a GC store. The is currently done through
`StoreOpaque::gc_store_mut` but this method is very commonly used
meaning that there are many many places to audit for lazily allocating a
GC store. The reason that this needs an audit is that lazy allocation
is an async operation right now that must be on a fiber and is something
I'm looking to fix as part of #11262.
This commit performs a few refactorings to achieve this:
* `gc_store_mut` is renamed to `ensure_gc_store`. This is intended to be
an `async` function in the future and clearly demarcates where lazy
allocation of a GC store is occurring.
* `require_gc_store{,_mut}` is now added which is a pure accessor of the
GC store with no lazy allocation. Most locations previously using
`gc_store_mut` are updated to use this instead.
Documentation is added to store methods to clearly indicate which ones
are allocating and which ones should only be called in a context where
allocation should already have happened.
* Fix configured build
* Relax GC store restrictions in more places
* Review comments on documentation
* Move `ensure_gc_store` calls during instantiation
Instead update `needs_gc_heap` with the tables that are added to a
module and rely on instantiation to create the GC heap.
* Shuffle around some code
* Fix CI and review comments
* Add in a few more i31 cases for externref
* Refactor `AbortHandle`, renamed to `JoinHandle` This commit is inspired by recent discussions about providing more guarantees around dropping WASI resources. This commit renames `wasmtime::component::AbortHandle` to `wasmtime::component::JoinHandle` and additionally implements `Future for JoinHandle` to know when the associated task's future has been dropped. The renaming is intended to more closely align with `tokio::task::JoinHandle` where `tokio::task::AbortHandle` is notably different and doesn't have a `Future` implementation. The `Future` implementation helps embedders know exactly when a value has been dropped and synchronize on that. * Clarify lack of abort-on-drop behavior
* refactor: move `File` and `Dir` to top-level Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * refactor: extract filesystem utilities to top-level Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * chore: update `wasi:filesystem@0.3` WIT Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * chore: port p2 filesystem test Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * feat(wasip3): add filesystem stubs Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * chore(wasip3): use trapping errors is fs for consistency with refactors for sockets Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * feat(wasip3): implement `wasi:filesystem` without reads Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * chore: remove unused enums Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * refactor: remove `NewTimestamp` enum Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * refactor(p2): check FD types before permissions Previously, `wasi:filesystem` functions taking two directory FDs as arguments, would check permissions on the source directory before ensuring that target FD is also a directory. This order has now been changed and first implementations ensure that both FDs are directories and only then check permissions. This should not have any functional differences in guest applications Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * refactor(fs): remove `Advice` enum Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * refactor(sockets): remove `ResultWriteTask` Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * feat(wasip3): implement `wasi:filesystem` reads Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * chore(p3): ignore FS test due to runtime panic Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * fix: make `filesystem` module public Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * feat(wasip3): abort filesystem tasks on descriptor drop Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * Revert "feat(wasip3): abort filesystem tasks on descriptor drop" This reverts commit 40415b52f79a33c376a2a875ffecb1d0a01c7903. Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * fix: avoid double `Accessor` entry Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * fix(p3): correctly handle FS I/O Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * fix(fs-p3): expect unreachable enums on Windows prtest:full Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * fix(p3): correctly handle Windows read_dir Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> * refactor: reorder read_dir conditional Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net> --------- Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
For real this time